import time
import traceback
import socket, ssl
import db_cloud
import CONSTANTS
import CMS
import threading
from threading import Thread


class NotiCloud:
    """
    Major Worker for CMS notification
    """
    def __init__(self):
#         threading.Thread.__init__(self)
        self.db_pool = db_cloud.NotiCloud()
        self.v_task_lock = threading.Condition()
        self.task = ''
        self.cr_task = ''

    def work(self):
        Thread(target=self.check_task_update).start()
        v_queued_log = self.db_pool.pop_queued_log()
        while v_queued_log:
            v_queued_log = eval(v_queued_log)
            if len(v_queued_log) == 5:
                self.db_pool.log(v_queued_log[0], v_queued_log[1], v_queued_log[2], v_queued_log[3], v_queued_log[4])
            v_queued_log = self.db_pool.pop_queued_log()
        while True:
            self.cr_task = self.db_pool.get_task()
            if self.cr_task:
                v_task = dict(zip(('task_id', 'message', 'type', 'app_id', 'platform_id', 'status', 'tokens', 'usernames', 'send_time', 'created_time'), self.cr_task))
                with self.v_task_lock:
                    self.task = self.cr_task
                    self.v_task_lock.wait(int(v_task.get('send_time')) - int(time.time()))
                    if self.task != self.cr_task:
                        continue
                v_pusher = NotiCloud_Pusher(self.db_pool, self.db_pool.gt_all(v_task))
                v_new_status = self.db_pool.gt_done(v_task['task_id'])
                if v_new_status == 2:
                    v_pusher.work()
                    self.db_pool.update_task_status(v_task['task_id'], CONSTANTS.STATUS.SUCCESS)
            time.sleep(1)

    def check_task_update(self):
        print 'begin update'
        while True:
            time.sleep(5)
            v_task = self.db_pool.get_task()
            if v_task != self.cr_task:
                with self.v_task_lock:
                    self.task = v_task
                    self.v_task_lock.notifyAll()
        

class NotiCloud_Pusher:
    """
    Worker for pushing off-line notifications to tokens queued by NotiCloud worker
    """
    def __init__(self, i_db_pool, i_task_queue_name):
        self.db_pool = i_db_pool
        self.queues = i_task_queue_name
        if self.queues:
            for queue in self.queues:
                if queue:
                    self.task_id = queue.split('_')[0]
                    break
        
#------------------------------------------------------------------------------ 
    def work(self):
        v_workers = []
        while self.queues:
            # get token list's redis key
            v_task_queue = self.queues[0]
            if not v_task_queue:
                try:
                    self.queues.remove(v_task_queue)
                except ValueError:
                    pass
                continue
#             v_task_id = v_task_queue.split('_')[0]
            v_app_id = v_task_queue.split('_')[1]
            v_platform = v_task_queue.split('_')[2]
            v_msg = v_task_queue[len(self.task_id) + len(v_app_id) + len(v_platform) + 3:]
            # taskid_appid_platform_msg
            if v_platform == 'android':
                v_worker = threading.Thread(target=CMS.Android.push, args=(v_task_queue, v_msg, int(v_app_id)))
            elif v_platform == 'ios':
                v_worker = threading.Thread(target=CMS.iOS.push, args=(v_task_queue, v_msg, int(v_app_id)))
            else:
                self.queues.remove(v_task_queue)
                continue
            v_worker.start()
            v_workers.append(v_worker)
            self.queues.remove(v_task_queue)
        for worker in v_workers:
            worker.join()
        print 'done task'